/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package MeteoCal.manager;

import MeteoCal.bean.exceptions.RollbackFailureException;
import MeteoCal.controller.EventJpaController;
import MeteoCal.controller.InvitationJpaController;
import MeteoCal.entity.Event;
import MeteoCal.entity.Invitation;
import MeteoCal.entity.InvitationPK;
import MeteoCal.entity.Schedule;
import MeteoCal.entity.User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.transaction.UserTransaction;

/**
 *
 * @author Guttadoro, Iommazzo, Saullo
 */
@Stateless
public class InvitationManager {

    @PersistenceContext
    private EntityManager em;
    
    @EJB
    private EventManager evm;
    
    public void addInvitation(Invitation i) {
        
        em.persist(i);
        em.flush();
    }

    public List<Invitation> retrieveInvitationByEventAndUserResponse(Event idEvent){
        TypedQuery<Invitation> query = em.createNamedQuery(Invitation.findByResponseAndEvent, Invitation.class);
        query.setParameter("response", "yes");
        query.setParameter("idEvent", idEvent);
        return query.getResultList();
    }
    
    public Collection<Invitation> getInvitation(Event e) {
        
       TypedQuery<Invitation> query = em.createNamedQuery("Invitation.findByIdEvent", Invitation.class);
       query.setParameter("idEvent", e.getIdEvent());
       List<Invitation> result = query.getResultList();
        
       return result;
            
    }
    
    public void changeResponseMaybe(User u, Event e){
        Invitation inv =  em.find(Invitation.class, new InvitationPK(u.getEmail(),e.getIdEvent()));
        System.err.println("Invito trovato ----> " + inv + inv.getResponse());
        e.getScheduleCollection().remove(u.getIdSchedule());
        inv.setResponse("Maybe");
        System.err.println("Qua sei maybe?????????????????????????'" + inv.getResponse());
        em.merge(inv);
        em.merge(e);
        em.flush();
    }
    
    public void removeInvitations(List<User> listu, Event e) {
        
        //em.setFlushMode(FlushModeType.COMMIT);

        for (User u: listu){
            e.getScheduleCollection().remove(u.getIdSchedule());
            em.merge(e);
            
            
            Invitation i = em.find(Invitation.class, new InvitationPK(u.getEmail(),e.getIdEvent()));
            System.err.println("..... Find invitation: "+i);
            em.remove(i);
            em.flush();
            //u.getIdSchedule().getEventCollection().remove(e);
            
        }
        
        
    }

    public List<Invitation> getInvitationsReceived(String email) {
       
        List<Invitation> l = new ArrayList<>();
        
        TypedQuery<Invitation> query = em.createNamedQuery("Invitation.findByIdUser", Invitation.class);
        query.setParameter("idUser", email);
        query.setHint("javax.persistence.cache.storeMode", "REFRESH");
        l.addAll(query.getResultList());
        return l;
        
    }
    
    public List<List<Invitation>> getInvitationsSent(User u) {
       
        
        TypedQuery<Event> query1 = em.createNamedQuery("Event.findByIdCreator", Event.class);
        query1.setParameter("idCreator", u);
        
        List<List<Invitation>> list = new ArrayList<>();
        
        for (Event e: query1.getResultList()){
        
            List<Invitation> temp = new ArrayList<>();
            List<Invitation> rminv = new ArrayList<>();
            
            TypedQuery<Invitation> query2 = em.createNamedQuery("Invitation.findByIdEvent", Invitation.class);
            query2.setParameter("idEvent", e.getIdEvent());
            
            for(Invitation i: query2.getResultList())
                if (!i.getEvent().getDateEnd().before(new Date()))
                    temp.add(i);
                else rminv.add(i);
            
            if (!temp.isEmpty())
                list.add(temp);
            
            if (!rminv.isEmpty())
                remove(rminv);
            
        }
                
        return list;
        
    }

    public Boolean update(List<Invitation> receivedin) throws RollbackFailureException, Exception {
       
        Boolean check = true;

        em.setFlushMode(FlushModeType.COMMIT);
        for(Invitation i: receivedin){
            
            Event e = i.getEvent();
            
            List<Schedule> scList = new ArrayList<>();
            
            scList.addAll(e.getScheduleCollection());
            Schedule sch = i.getUser().getIdSchedule();
            System.err.println("Schedulelist 1-->" + scList + " e: "+e);
            System.err.println("Invitation 1-->" + i.getResponse() + " i: "+i);
            System.err.println("User 1-->" + i.getUser() );
            if (i.getResponse().equals("No") || i.getResponse().equals("Maybe")){
                if(scList.contains(i.getUser().getIdSchedule())){
                    //scList.remove(i.getUser().getIdSchedule());
                    e.getScheduleCollection().remove(i.getUser().getIdSchedule());
                   // sch.getEventCollection().remove(e);
                }
            }
            System.err.println("Schedulelist 2 -->" + scList+ " e: "+e);
           // e.setScheduleCollection(scList);
            i.setDateTimeResponse(new Date());
            
           //em.merge(sch);
            em.merge(e);
            
            em.merge(i);   
            em.flush();
            
        }
        
        for(Invitation i: receivedin){
            
            Event e = i.getEvent();
            List<Schedule> scList = new ArrayList<>();
            scList.addAll(e.getScheduleCollection());
            System.err.println("Schedulelist 3 -->" + scList+ " e: "+e);
            if (i.getResponse().equals("Yes")){
                if(!scList.contains(i.getUser().getIdSchedule())){
                    Event ev = e.setHoursInDate();
                    
                    if(evm.overlapping(i.getUser(), ev) == null){
                        scList.add(i.getUser().getIdSchedule());
                        System.err.println("sc add the schedule --> " + i.getUser().getIdSchedule());
                    }
                    else {
                        i.setResponse(em.find(Invitation.class, i.getInvitationPK()).getResponse());
                        check = false;
                    }
                }
            }
            System.err.println("Schedulelist 4 -->" + scList+ " e: "+e);
            e.setScheduleCollection(scList);
            i.setDateTimeResponse(new Date());
            
            em.merge(e);
            em.merge(i);
            em.flush();
        }
        return check;

    }

    private void remove(List<Invitation> result) {
        
        for (Invitation i : result) {
            
            em.remove(i);
            
        }
            
    }
}
